package se.webbzon.oschi01.worldobject;

import javax.vecmath.Vector3d;

import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;

public abstract class WorldMovableObject extends WorldStaticObject {
	
	// The velocity of the instance
	private final Vector3d velocity;
	
	// The acceleration of the instance
	private final Vector3d acceleration;

	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new abstract WorldMovableObject with a given
	 * appearance and a given set of registered methods. The 
	 * 2D-depth of the instance will be equal to zero. **/
	public WorldMovableObject(int registeredMethods,
			Appearance3D appearance) {
		this(registeredMethods,0,appearance);
	}
	
	/** Creates a new abstract WorldMovableObject with a given
	 * appearance and a given set of registered methods. The 
	 * 2D-depth of the instance is given by the input depth2D. **/
	public WorldMovableObject(int registeredMethods, int depth2D,
			Appearance3D appearance) {
		super(registeredMethods, depth2D, appearance);
		this.velocity = new Vector3d();
		this.acceleration = new Vector3d();
	}
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Returns a copy of the velocity of the instance. **/
	public Vector3d getVelocity() {
		return new Vector3d(velocity.x,velocity.y,velocity.z);
	}
	
	/** Returns the x-component of the velocity. **/
	public double getXVelocity() {
		return velocity.x;
	}
	
	/** Returns the y-component of the velocity. **/
	public double getYVelocity() {
		return velocity.y;
	}
	
	/** Returns the z-component of the velocity. **/
	public double getZVelocity() {
		return velocity.z;
	}
	
	/** Sets the velocity of the instance. **/
	public void setVelocity(double xVelocity, double yVelocity, double zVelocity) {
		velocity.set(xVelocity, yVelocity, zVelocity);
	}
	
	/** Returns a copy of the acceleration of the instance. **/
	public Vector3d getAcceleration() {
		return new Vector3d(acceleration.x,acceleration.y,acceleration.z);
	}
	
	/** Returns the x-component of the acceleration. **/
	public double getXAcceleration() {
		return acceleration.x;
	}
	
	/** Returns the y-component of the acceleration. **/
	public double getYAcceleration() {
		return acceleration.y;
	}
	
	/** Returns the z-component of the acceleration. **/
	public double getZAcceleration() {
		return acceleration.z;
	}
	
	/** Sets the acceleration of the instance. **/
	public void setAcceleration(double xAcceleration, 
								double yAcceleration, 
								double zAcceleration) {
		acceleration.set(xAcceleration, yAcceleration, zAcceleration);
	}
	
	@Override public void onStepEnd(WorldArea world) {
		setPosition(getX() + velocity.x, getY() + velocity.y, getZ() + velocity.z);
		super.onStepEnd(world);
		setVelocity(velocity.x + acceleration.x,
					velocity.y + acceleration.y,
					velocity.z + acceleration.z);
	}

}
